#include <iostream>
#include <fstream>
#include "pb_cfg_treasure.pb.h"

#include "CTreasureMgr.h"
#include "commmsg.h"
#include "../mainctrl.h"

#include "MsgOtherInfo.pb.h"
#include "MsgTreasure.pb.h"
#include "MsgStorage.pb.h"
#include "MsgGM.pb.h"
#include "CTSizeString.h"

int CTreasureMgr::LoadConfig(const char* szLogPath)
{
    int iRet = 0;
    int iIndex = 0;
    if (szLogPath == NULL)
    {
        CT_ERROR(("Treasure Config Path is null"));
        return RET_SYSTEM_FAIL;
    }

    _stTreasureCfg.InitConfig();

    pb_cfg_treasure stTreasurePBCfg;
    std::fstream stFileInput(szLogPath, std::ios::in | std::ios::binary);
    if (!stTreasurePBCfg.ParseFromIstream(&stFileInput))
    {
        CT_ERROR(("Failed to Parse TreasureCfg!"));
        return RET_SYSTEM_FAIL;
    }

    CT_TRACE(("Treasure Up Config Count(%d)",
              stTreasurePBCfg.treasure_up_cfg_rows_size()));

    CTreasureUpCfgData stUpCfgData;
    for (int i = 0; i < stTreasurePBCfg.treasure_up_cfg_rows_size(); ++i)
    {
        const pb_cfg_treasure_pb_cfg_treasure_up_cfg_unit& stTreasurePBUpUnit 
            = stTreasurePBCfg.treasure_up_cfg_rows(i);

        stUpCfgData.Clear();
    
        stUpCfgData.SetLevel((short)stTreasurePBUpUnit.level());
        stUpCfgData.SetSpirit(stTreasurePBUpUnit.spirit());
        stUpCfgData.SetSilver(stTreasurePBUpUnit.silver());
        stUpCfgData.SetAttrType(stTreasurePBUpUnit.attr_type());
        stUpCfgData.SetAttrData(stTreasurePBUpUnit.attr_data());

        if (stUpCfgData.GetAttrData() < 0 ||
                (stUpCfgData.GetAttrType() > 0 &&
                    !CPlayerAttr::IsValidAttrType(stUpCfgData.GetAttrType())))
        {
            return ERROR_TREASURE_OVER_LEVEL;
        }

        iRet = AddTreasureUpCfg(stUpCfgData);
        CT_RETURN(iRet);
    }

    CT_TRACE(("Treasure Config Count(%d)",
              stTreasurePBCfg.treasure_cfg_rows_size()));

    T_TREASURE_ACT_DATA aiTreasureOrder;
    aiTreasureOrder.Clear();

    CTreasureCfgData stCfgData;
    for (int i = 0; i < stTreasurePBCfg.treasure_cfg_rows_size(); ++i)
    {
        const pb_cfg_treasure_pb_cfg_treasure_cfg_unit& stTreasurePBCfgUnit 
            = stTreasurePBCfg.treasure_cfg_rows(i);

        stCfgData.Clear();
    
        stCfgData.SetResID(stTreasurePBCfgUnit.id());
        stCfgData.SetOrder(stTreasurePBCfgUnit.order());
        stCfgData.SetStatusID(0, stTreasurePBCfgUnit.status_0());
        stCfgData.SetStatusID(1, stTreasurePBCfgUnit.status_1());
        stCfgData.SetStatusID(2, stTreasurePBCfgUnit.status_2());
        stCfgData.SetStatusID(3, stTreasurePBCfgUnit.status_3());
        stCfgData.SetStatusID(4, stTreasurePBCfgUnit.status_4());
        stCfgData.SetStatusID(5, stTreasurePBCfgUnit.status_5());
        stCfgData.SetStatusID(6, stTreasurePBCfgUnit.status_6());
        stCfgData.SetStatusID(7, stTreasurePBCfgUnit.status_7());
        stCfgData.SetStatusID(8, stTreasurePBCfgUnit.status_8());
        stCfgData.SetStatusID(9, stTreasurePBCfgUnit.status_9());
        stCfgData.SetStatusID(10, stTreasurePBCfgUnit.status_10());
        stCfgData.SetStatusID(11, stTreasurePBCfgUnit.status_11());
        stCfgData.SetStatusID(12, stTreasurePBCfgUnit.status_12());
        stCfgData.SetStatusID(13, stTreasurePBCfgUnit.status_13());
        stCfgData.SetStatusID(14, stTreasurePBCfgUnit.status_14());
        stCfgData.SetStatusID(15, stTreasurePBCfgUnit.status_15());
        stCfgData.SetStatusID(16, stTreasurePBCfgUnit.status_16());
        stCfgData.SetStatusID(17, stTreasurePBCfgUnit.status_17());
        stCfgData.SetStatusID(18, stTreasurePBCfgUnit.status_18());
        stCfgData.SetStatusID(19, stTreasurePBCfgUnit.status_19());
        stCfgData.SetStatusID(20, stTreasurePBCfgUnit.status_20());
        stCfgData.SetStatusID(21, stTreasurePBCfgUnit.status_21());
        stCfgData.SetStatusID(22, stTreasurePBCfgUnit.status_22());
        stCfgData.SetStatusID(23, stTreasurePBCfgUnit.status_23());
        stCfgData.SetStatusID(24, stTreasurePBCfgUnit.status_24());
        stCfgData.SetStatusID(25, stTreasurePBCfgUnit.status_25());
        stCfgData.SetStatusID(26, stTreasurePBCfgUnit.status_26());
        stCfgData.SetStatusID(27, stTreasurePBCfgUnit.status_27());
        stCfgData.SetStatusID(28, stTreasurePBCfgUnit.status_28());
        stCfgData.SetStatusID(29, stTreasurePBCfgUnit.status_29());
        stCfgData.SetStatusID(30, stTreasurePBCfgUnit.status_30());

        for (int j = 0; j < stCfgData.GetStatusIDSize(); ++j)
        {
            if (stCfgData.GetStatusID(j) > 0)
            {
                iIndex = CMainCtrl::m_pstMain->m_stStatusMgr.FindStatusCfg(
                            stCfgData.GetStatusID(j));
                if (iIndex < 0)
                {
                    CT_WARNING(("unknow status(%d) config",
                                stCfgData.GetStatusID(j)));
                    CT_RETURN(ERROR_STATUS_EMPTY_CFG);
                }
            }
        }

        aiTreasureOrder.AddOneItem(stCfgData.GetOrder());

        iRet = AddTreasureCfg(stCfgData);
        CT_RETURN(iRet);
    }

    iRet = CheckValidOrder(aiTreasureOrder);//检查所有秘宝的显示次序
    CT_RETURN(iRet);

    return 0;
}

int CTreasureMgr::AddTreasureCfg(CTreasureCfgData& stCfgData)
{
    return _stTreasureCfg.AddConfig(stCfgData);
}

int CTreasureMgr::FindTreasureCfg(int iResID)
{
    return _stTreasureCfg.FindConfig(iResID);
}

CTreasureCfgData& CTreasureMgr::GetTreasureCfg(int iIndex)
{
    return _stTreasureCfg.GetConfig(iIndex);
}

int CTreasureMgr::AddTreasureUpCfg(CTreasureUpCfgData& stCfgData)
{
    return _stTreasureCfg.AddUpConfig(stCfgData);
}

int CTreasureMgr::FindTreasureUpCfg(short shLevel)
{
    return _stTreasureCfg.FindUpConfig(shLevel);
}

CTreasureUpCfgData& CTreasureMgr::GetTreasureUpCfg(int iIndex)
{
    return _stTreasureCfg.GetUpConfig(iIndex);
}

bool CTreasureMgr::IsValidTreasureID(short shResID)
{
    return (shResID > 0 && shResID <= MAX_TREASURE_ACT_COUNT);
}

int CTreasureMgr::FindTreasureIndex(short shResID,
        CPlayerDetailInfo& stPlayerDetail)
{
    if (!IsValidTreasureID(shResID))
    {
        return -1;//因为返回下标 所以这里必须返回负数
    }

    CTreasureData& stTreasureData = stPlayerDetail._stTreasureData;

    //为了以后的扩展 这里采用可伸缩的数组存放 需要循环
    for (int i = 0; i < stTreasureData._stTreasureList.Size(); ++i)
    {
        CTreasureUnit& stTreasureUnit = stTreasureData._stTreasureList[i];
        if (stTreasureUnit._shResID == shResID)
        {
            return i;
        }
    }

    return -1;//因为返回下标 所以这里必须返回负数
}

CTreasureUnit& CTreasureMgr::GetTreasureUnit(int iIndex,
        CPlayerDetailInfo& stPlayerDetail)
{
    return stPlayerDetail._stTreasureData._stTreasureList[iIndex];
}

bool CTreasureMgr::IsTreasureExist(CTreasureUnit& stTreasureUnit)
{
    //检查宿主类型
    if (0 != stTreasureUnit._chHostType &&
        GAME_OBJ_TYPE_PLAYER != stTreasureUnit._chHostType &&
        GAME_OBJ_TYPE_PARTNER != stTreasureUnit._chHostType)
    {
        CT_ERROR(("treasure(%d) host type(%d) error",stTreasureUnit._shResID,
            stTreasureUnit._chHostType));
        return false;
    }

    //检查宿主配位
    if (TREASURE_HOST_POS_NULL != stTreasureUnit._chHostPos &&
        TREASURE_HOST_POS_ONE != stTreasureUnit._chHostPos &&
        TREASURE_HOST_POS_TWO != stTreasureUnit._chHostPos)
    {
        CT_ERROR(("treasure(%d) host pos(%d) error",stTreasureUnit._shResID,
            stTreasureUnit._chHostPos));
        return false;
    }

    //检查秘宝配置
    if (FindTreasureCfg(stTreasureUnit._shResID) < 0)
    {
        CT_ERROR(("treasure(%d) config empty",stTreasureUnit._shResID));
        return false;
    }

    //检查秘宝等级
    if (stTreasureUnit._shLevel < 0 ||
        stTreasureUnit._shLevel >= MAX_TREASURE_UP_LEVEL)
    {
        CT_ERROR(("treasure(%d) level(%d) error",stTreasureUnit._shResID,
            stTreasureUnit._shLevel));
        return false;
    }

    return true;
}

bool CTreasureMgr::IsTreasureOnPut(CTreasureUnit& stTreasureUnit)
{
    return (stTreasureUnit._chHostType != GAME_OBJ_TYPE_NULL &&
            stTreasureUnit._chHostPos != TREASURE_HOST_POS_NULL &&
            stTreasureUnit._uiHostID > 0);
}

int CTreasureMgr::ChkTreasureInfo(short shResID,
        CPlayerDetailInfo& stPlayerDetail)
{
    int iIndex = 0;

    if (!IsValidTreasureID(shResID))
    {
        return ERROR_TREASURE_REQ_INFO;
    }

    iIndex = FindTreasureIndex(shResID, stPlayerDetail);
    if (iIndex < 0)
    {
        return ERROR_TREASURE_REQ_INFO;
    }

    CTreasureUnit& stTreasureUnit = GetTreasureUnit(iIndex, stPlayerDetail);

    if (!IsTreasureExist(stTreasureUnit))
    {
        return ERROR_TREASURE_NOT_EXIST;
    }

    return 0;
}

int CTreasureMgr::CalcTreasureAttr(CPlayerDetailInfo& stPlayerDetail,
        CPlayerAttr& stBaseAttr, char chHostType, unsigned int uiHostID)
{
    if (GAME_OBJ_TYPE_PLAYER != chHostType &&
            GAME_OBJ_TYPE_PARTNER != chHostType)
    {
        return 0;
    }

    if (uiHostID <= 0)
    {
        return 0;
    }

    int iIndex = 0;
    CTreasureData& stTreasureData = stPlayerDetail._stTreasureData;

    for (int i = 0; i < stTreasureData._stTreasureList.Size(); ++i)
    {
        CTreasureUnit& stTreasureUnit = stTreasureData._stTreasureList[i];
        if (stTreasureUnit._chHostType == chHostType &&
            stTreasureUnit._uiHostID == uiHostID)
        {
            iIndex = FindTreasureUpCfg(stTreasureUnit._shLevel);
            if (iIndex < 0)
            {
                continue;
            }

            CTreasureUpCfgData& stUpCfgData = GetTreasureUpCfg(iIndex);

            if (!CPlayerAttr::IsValidAttrType(stUpCfgData.GetAttrType()))
            {
                continue;
            }

            stBaseAttr.AddAttr(stUpCfgData.GetAttrType(),
                stUpCfgData.GetAttrData());
        }
    }

    return 0;
}

int CTreasureMgr::RecalcHostAttr(CTreasureUnit& stTreasureUnit,
        CPlayerBaseInfo& stPlayerBase, CPlayerDetailInfo& stPlayerDetail,
        CPlayerOnlineData& stPlayerOnline)
{
    if (GAME_OBJ_TYPE_PLAYER == stTreasureUnit._chHostType &&
            stTreasureUnit._uiHostID == stPlayerBase._uiGID)
    {
        CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(stPlayerBase._uiGID,
            NOTIFY_ROLE_ATTR);
    }
    else if (GAME_OBJ_TYPE_PARTNER == stTreasureUnit._chHostType)
    {
        CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(stPlayerBase._uiGID,
            NOTIFY_PARTNER_ATTR, (short)stTreasureUnit._uiHostID);
    }

    return 0;
}

int CTreasureMgr::TreasureUpLevel(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CPlayerOnlineData& stPlayerOnline,
        MsgReqTreasure& stReq)
{
    if (!stReq.has_treasure_id())
    {
        return RET_REQ_NOT_COMPLETE;
    }

    short shResID = (short)stReq.treasure_id();

    int iRet = 0;
    int iIndex = 0;

    //存在性检查流程
    iRet = ChkTreasureInfo(shResID, stPlayerDetail);
    CT_RETURN(iRet);

    iIndex = FindTreasureIndex(shResID, stPlayerDetail);
    if (iIndex < 0)
    {
        return ERROR_TREASURE_REQ_INFO;
    }

    CTreasureUnit& stTreasureUnit = GetTreasureUnit(iIndex, stPlayerDetail);

    //是否满级
    if (stTreasureUnit._shLevel >= MAX_TREASURE_UP_LEVEL - 1)
    {
        return ERROR_TREASURE_MAX_LEVEL;
    }

    short shNewLevel = stTreasureUnit._shLevel + 1;

    iIndex = FindTreasureCfg(shResID);
    if (iIndex < 0)
    {
        return ERROR_TREASURE_EMPTY_CFG;
    }

    CTreasureCfgData& stTreasureCfg = GetTreasureCfg(iIndex);

    iIndex = FindTreasureUpCfg(shNewLevel);
    if (iIndex < 0)
    {
        return ERROR_TREASURE_OVER_LEVEL;
    }

    CTreasureUpCfgData& stTreasureUpCfg = GetTreasureUpCfg(iIndex);

    //检查状态配置
    if (stTreasureCfg.GetStatusIDSize() < shNewLevel)
    {
        return ERROR_TREASURE_EMPTY_CFG;
    }

    //检查配置中灵力银两合理性
    if (!stTreasureUpCfg.IsValidValue())
    {
        return ERROR_TREASURE_EMPTY_UP_CFG;
    }

    CTreasureData& stTreasureData = stPlayerDetail._stTreasureData;

    //检查秘宝灵力
    iRet = CPlayerBaseInfo::CheckIntValue(stTreasureData._iSpirit,
        0 - stTreasureUpCfg.GetSpirit());
    if (iRet)
    {
        return ERROR_TREASURE_LESS_SPIRIT;
    }

    //检查角色银两
    iRet = CPlayerBaseInfo::CheckInt64Value(stPlayerBase._i64Silver, 0 - stTreasureUpCfg.GetSilver());
    if (iRet)
    {
        return ERROR_SILVER_LESS;
    }

    //减去秘宝灵力
    iRet = CPlayerBaseInfo::ChangeIntValue(stTreasureData._iSpirit, 0 - stTreasureUpCfg.GetSpirit());
    if (iRet)
    {
        return ERROR_TREASURE_LESS_SPIRIT;
    }

    //减去角色银两
    iRet = CMainCtrl::m_pstMain->m_stItemMgr.SubSilver(stPlayerBase, stTreasureUpCfg.GetSilver(), 0);
    if (iRet)
    {
        return ERROR_SILVER_LESS;
    }

    stTreasureUnit._shLevel = shNewLevel;
    
    CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(stPlayerDetail._uiGID, NOTIFY_USER_MONEY);

    //前端需要treasure detail刷新面板
    SendDetailTreasureToFront(stPlayerDetail, shResID);

    RecalcHostAttr(stTreasureUnit, stPlayerBase, stPlayerDetail, stPlayerOnline);

    if (GAME_OBJ_TYPE_PLAYER != stTreasureUnit._chHostType)
    {
        CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(stPlayerDetail._uiGID,
            NOTIFY_ROLE_INFO);
    }

    //跑马灯
    if (stTreasureUnit._shLevel % 5 == 0)
    {
        MsgTips stTips;
        stTips.set_type(1009);

        stTips.add_tip_argument(CMainCtrl::m_pstMain->m_stRoleMgr.GetRoleName(
            stPlayerDetail._uiGID));
        stTips.add_tip_argument(CTStringUtils::IntToString(shResID));
        stTips.add_tip_argument(
            CTStringUtils::IntToString(stTreasureUnit._shLevel));
        CMainCtrl::m_pstMain->SendOnlineTips(stTips);
    }

    return 0;
}

int CTreasureMgr::PutOnTreasureUnit(CTreasureUnit& stTreasureUnit,
        const MsgTreasureUnit& stMsgTreasureUnit)
{
    stTreasureUnit._chHostType = (char)stMsgTreasureUnit.type();
    stTreasureUnit._chHostPos = (char)stMsgTreasureUnit.pos();
    stTreasureUnit._uiHostID = (unsigned int)stMsgTreasureUnit.id();

    return 0;
}

int CTreasureMgr::CanPutOnTreasure(char chHostType, char chHostPos,
        unsigned int uiHostID, CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CTreasureUnit& stSourceUnit)
{
    if (TREASURE_HOST_POS_ONE != chHostPos &&
        TREASURE_HOST_POS_TWO != chHostPos)
    {
        CT_WARNING(("role(%u) treasure host pos(%d) error!",
                    stPlayerDetail._uiGID,chHostPos));
        return ERROR_TREASURE_OPERATION_INFO;
    }

    int iIndex = 0;
    if (GAME_OBJ_TYPE_PLAYER == chHostType)
    {
        if (uiHostID != stPlayerDetail._uiGID)
        {
            CT_WARNING(("role(%u) treasure host id(%u) error!",
                        stPlayerDetail._uiGID,uiHostID));
            return ERROR_TREASURE_OPERATION_INFO;
        }

        if (TREASURE_HOST_POS_TWO == chHostPos &&
                stPlayerBase._shLevel < MAX_TREASURE_POS_TWO_LIMIT)
        {
            return ERROR_TREASURE_POS_LIMIT;
        }
    }
    else if (GAME_OBJ_TYPE_PARTNER == chHostType)
    {
        iIndex = stPlayerDetail._stUserPartner.FindActData((short)uiHostID);
        if (iIndex < 0)
        {
            CT_WARNING(("role(%u) partner(%d) not in act!",
                        stPlayerDetail._uiGID,(short)uiHostID));
            return ERROR_PARTNER_NOT_IN_ACT;
        }

        CPartnerActData& stActData =
            stPlayerDetail._stUserPartner.GetPartnerActData(iIndex);
        if (TREASURE_HOST_POS_TWO == chHostPos &&
                stActData._shLevel < MAX_TREASURE_POS_TWO_LIMIT)
        {
            return ERROR_TREASURE_POS_LIMIT;
        }
    }
    else 
    {
        CT_WARNING(("role(%u) treasure host type(%d) error!",
                    stPlayerDetail._uiGID,chHostType));
        return ERROR_TREASURE_OPERATION_INFO;
    }

    CTreasureData& stTreasureData = stPlayerDetail._stTreasureData;

    for (int i = 0; i < stTreasureData._stTreasureList.Size(); ++i)
    {
        CTreasureUnit& stTreasureUnit = stTreasureData._stTreasureList[i];
        if (stTreasureUnit._chHostType == chHostType &&
            stTreasureUnit._chHostPos == chHostPos &&
            stTreasureUnit._uiHostID == uiHostID)
        {
            stSourceUnit = stTreasureUnit;
            break;
        }
    }

    return 0;
}

int CTreasureMgr::ChkTreasurePutOn(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail,
        const MsgTreasureUnit& stMsgTreasureUnit, CTreasureUnit& stSourceUnit)
{
    int iRet = 0;
    if (GAME_OBJ_TYPE_PLAYER == stMsgTreasureUnit.type() ||
        GAME_OBJ_TYPE_PARTNER == stMsgTreasureUnit.type())
    {
        iRet = CanPutOnTreasure((char)stMsgTreasureUnit.type(),
                (char)stMsgTreasureUnit.pos(),
                (unsigned int)stMsgTreasureUnit.id(), stPlayerBase,
                stPlayerDetail, stSourceUnit);
        CT_RETURN(iRet);
    }
    else
    {
        CT_WARNING(("role(%u) put on treasure unknow obj type(%d)",
                    stPlayerDetail._uiGID,stMsgTreasureUnit.type()));
        return ERROR_TREASURE_OPERATION_INFO;
    }

    return 0;
}

int CTreasureMgr::TreasurePutOn(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CPlayerOnlineData& stPlayerOnline,
        MsgReqTreasure& stReq)
{
    if (!stReq.has_treasure_id() || !stReq.has_treasure_unit())
    {
        return RET_REQ_NOT_COMPLETE;
    }

    short shResID = (short)stReq.treasure_id();

    int iRet = 0;
    int iIndex = 0;

    //存在性检查流程
    iRet = ChkTreasureInfo(shResID, stPlayerDetail);
    CT_RETURN(iRet);

    iIndex = FindTreasureIndex(shResID, stPlayerDetail);
    if (iIndex < 0)
    {
        return ERROR_TREASURE_REQ_INFO;
    }

    //stTreasureUnitA选中操作的秘宝
    CTreasureUnit& stTreasureUnitA = GetTreasureUnit(iIndex, stPlayerDetail);

    CTreasureUnit stTreasureUnitATemp = stTreasureUnitA;

    //stTreasureUnitB目标秘宝位上原装配的秘宝
    CTreasureUnit stTreasureUnitB;
    stTreasureUnitB.Init();
    MsgTreasureUnit stMsgTreasureUnitB;

    iRet = ChkTreasurePutOn(stPlayerBase, stPlayerDetail, stReq.treasure_unit(),
        stTreasureUnitB);
    CT_RETURN(iRet);

    bool bSwap = false;
    bool bPutOnB = false;
    bool bPutOnA = false;
    bool bTakeOffB = false;
    bool bTakeOffA = false;

    ::google::protobuf::RepeatedField<int64> stReqIDList;
    stReqIDList.Clear();

    //选中秘宝未穿戴 目标秘宝为空装备位 直接穿上选中秘宝
    if (0 == stTreasureUnitB._chHostType && 0 == stTreasureUnitA._chHostType)
    {
        bPutOnA = true;
    }
    //选中秘宝已穿戴 目标秘宝为空装备位 先脱下选中秘宝再穿到目标秘宝位
    else if (0 == stTreasureUnitB._chHostType &&
             0 != stTreasureUnitA._chHostType)
    {
        bTakeOffA = true;
        bPutOnA = true;
    }
    //选中秘宝未穿戴 目标秘宝装备位非空 先脱下目标秘宝再穿选中秘宝到目标秘宝位
    else if (0 != stTreasureUnitB._chHostType &&
             0 == stTreasureUnitA._chHostType)
    {
        bTakeOffB = true;
        bPutOnA = true;
    }
    //选中秘宝已穿戴 目标秘宝装备位非空 不同类型宿主之间的交换 涉及宿主属性变化
    else if (0 != stTreasureUnitB._chHostType &&
             0 != stTreasureUnitA._chHostType &&
             stTreasureUnitB._chHostType != stTreasureUnitA._chHostType)
    {
        bTakeOffB = true;
        bTakeOffA = true;
        bPutOnB = true;
        bPutOnA = true;
    }
    //选中秘宝已穿戴 目标秘宝装备位非空 相同类型宿主之间的交换
    else if (0 != stTreasureUnitB._chHostType &&
             0 != stTreasureUnitA._chHostType &&
             stTreasureUnitB._chHostType == stTreasureUnitA._chHostType)
    {
        //相同的宿主类型 不同的宿主个体 涉及宿主属性变化
        if (stTreasureUnitB._uiHostID != stTreasureUnitA._uiHostID)
        {
            bTakeOffB = true;
            bTakeOffA = true;
            bPutOnB = true;
            bPutOnA = true;
        }
        //同一宿主不同装备位的交换 没有宿主属性变化
        else if (stTreasureUnitB._uiHostID == stTreasureUnitA._uiHostID &&
                 stTreasureUnitB._chHostPos != stTreasureUnitA._chHostPos)
        {
            bSwap = true;
        }
    }

    if (bTakeOffB)
    {
        if (GAME_OBJ_TYPE_PLAYER == stTreasureUnitB._chHostType ||
            GAME_OBJ_TYPE_PARTNER == stTreasureUnitB._chHostType)
        {
            MsgReqTreasure stTakeOffReq;
            stTakeOffReq.set_gid((int)stPlayerDetail._uiGID);
            stTakeOffReq.set_sub_type(CMD_TREASURE_SUB_TAKE_OFF);
            stTakeOffReq.set_treasure_id(stTreasureUnitB._shResID);
        
            iRet = TreasureTakeOff(stPlayerBase, stPlayerDetail, stPlayerOnline,
                stTakeOffReq);
            CT_RETURN(iRet);
        }
    }

    if (bTakeOffA)
    {
        if (GAME_OBJ_TYPE_PLAYER == stTreasureUnitA._chHostType ||
            GAME_OBJ_TYPE_PARTNER == stTreasureUnitA._chHostType)
        {
            MsgReqTreasure stTakeOffReq;
            stTakeOffReq.set_gid((int)stPlayerDetail._uiGID);
            stTakeOffReq.set_sub_type(CMD_TREASURE_SUB_TAKE_OFF);
            stTakeOffReq.set_treasure_id(stTreasureUnitA._shResID);
        
            iRet = TreasureTakeOff(stPlayerBase, stPlayerDetail, stPlayerOnline,
                stTakeOffReq);
            CT_RETURN(iRet);
        }
    }

    //拷贝临时变量
    if (bPutOnB)
    {
        stMsgTreasureUnitB.set_type(stTreasureUnitA._chHostType);
        stMsgTreasureUnitB.set_pos(stTreasureUnitA._chHostPos);
        stMsgTreasureUnitB.set_pos((int)stTreasureUnitA._uiHostID);
    }

    //必须先穿A才能穿B
    if (bPutOnA)
    {
        iRet = PutOnTreasureUnit(stTreasureUnitA, stReq.treasure_unit());
        CT_RETURN(iRet);

        RecalcHostAttr(stTreasureUnitA, stPlayerBase, stPlayerDetail,
            stPlayerOnline);

        stReqIDList.Add(stTreasureUnitA._shResID);
    }

    //必须先穿A才能穿B
    if (bPutOnB)
    {
        iIndex = FindTreasureIndex(stTreasureUnitB._shResID, stPlayerDetail);
        if (iIndex < 0)
        {
            return ERROR_TREASURE_REQ_INFO;
        }
        
        CTreasureUnit& stTreasureUnitBTmp =
            GetTreasureUnit(iIndex, stPlayerDetail);
        iRet = PutOnTreasureUnit(stTreasureUnitBTmp, stMsgTreasureUnitB);
        CT_RETURN(iRet);

        RecalcHostAttr(stTreasureUnitBTmp, stPlayerBase, stPlayerDetail,
            stPlayerOnline);

        stReqIDList.Add(stTreasureUnitBTmp._shResID);
    }

    if (bSwap)
    {
        iIndex = FindTreasureIndex(stTreasureUnitB._shResID, stPlayerDetail);
        if (iIndex < 0)
        {
            return ERROR_TREASURE_REQ_INFO;
        }
        
        CTreasureUnit& stTreasureUnitSwap =
            GetTreasureUnit(iIndex, stPlayerDetail);

        char chHostPos = stTreasureUnitA._chHostPos;
        stTreasureUnitA._chHostPos = stTreasureUnitSwap._chHostPos;
        stTreasureUnitSwap._chHostPos = chHostPos;

        //交换个体时候不重新计算宿主属性变化 需要单独下发个体信息
        if (GAME_OBJ_TYPE_PLAYER == stTreasureUnitA._chHostType)
        {
            CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(stPlayerDetail._uiGID,
                    NOTIFY_ROLE_INFO);
        }
        else if (GAME_OBJ_TYPE_PARTNER == stTreasureUnitA._chHostType)
        {
            CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(stPlayerDetail._uiGID,
                NOTIFY_PARTNER_INFO, (int)stTreasureUnitA._uiHostID);
        }

        stReqIDList.Add(stTreasureUnitA._shResID);
        stReqIDList.Add(stTreasureUnitSwap._shResID);
    }
     
    SendDetailTreasureToFront(stPlayerDetail, stReqIDList);

    return 0;
}

int CTreasureMgr::ClearTreasureUnit(CTreasureUnit& stTreasureUnit)
{
    stTreasureUnit._chHostType = GAME_OBJ_TYPE_NULL;
    stTreasureUnit._chHostPos = TREASURE_HOST_POS_NULL;
    stTreasureUnit._uiHostID = 0;

    return 0;
}

int CTreasureMgr::TreasureTakeOff(CPlayerBaseInfo& stPlayerBase,
        CPlayerDetailInfo& stPlayerDetail, CPlayerOnlineData& stPlayerOnline,
        MsgReqTreasure& stReq)
{
    if (!stReq.has_treasure_id())
    {
        return RET_REQ_NOT_COMPLETE;
    }

    short shResID = (short)stReq.treasure_id();

    int iRet = 0;
    int iIndex = 0;

    //存在性检查流程
    iRet = ChkTreasureInfo(shResID, stPlayerDetail);
    CT_RETURN(iRet);

    iIndex = FindTreasureIndex(shResID, stPlayerDetail);
    if (iIndex < 0)
    {
        return ERROR_TREASURE_REQ_INFO;
    }

    CTreasureUnit& stTreasureUnit = GetTreasureUnit(iIndex, stPlayerDetail);

    if (!IsTreasureOnPut(stTreasureUnit))
    {
        CT_ERROR(("role(%u) treasure(%d) not on put",stPlayerBase._uiGID,
            stTreasureUnit._shResID));
        return ERROR_TREASURE_REQ_INFO;
    }

    CTreasureUnit stTreasureUnitTemp = stTreasureUnit;

    ClearTreasureUnit(stTreasureUnit);

    RecalcHostAttr(stTreasureUnitTemp, stPlayerBase, stPlayerDetail,
        stPlayerOnline);

    SendDetailTreasureToFront(stPlayerDetail, shResID);

    return 0;
}

void CTreasureMgr::GetBriefTreasure(int iPos, CTreasureUnit& stTreasureUnit,
        MsgGridItemInfo& stMsgGridItem)
{
    stMsgGridItem.set_item_store_pos(iPos);
    stMsgGridItem.set_item_type(ITEM_TYPE_TREASURE);
    stMsgGridItem.set_item_count(1);
    stMsgGridItem.set_item_config_id(stTreasureUnit._shResID);
    stMsgGridItem.set_item_aux_info(CTStringUtils::Uint64ToString(stTreasureUnit._chHostPos, 10));
}

void CTreasureMgr::GetObjBaseTreasure(CPlayerDetailInfo& stPlayerDetail,
        MsgObjBase& stMsgObjBase, char chHostType, unsigned int uiHostID)
{
    CTreasureData& stTreasureData = stPlayerDetail._stTreasureData;

    int iCount = 0;

    for (int i = 0; i < stTreasureData._stTreasureList.Size() &&
                    iCount < MAX_TREASURE_OBJ_COUNT; ++i)
    {
        CTreasureUnit& stTreasureUnit = stTreasureData._stTreasureList[i];
        if (!IsValidTreasureID(stTreasureUnit._shResID))
        {
            continue;
        }

        if (stTreasureUnit._chHostType != chHostType ||
            stTreasureUnit._uiHostID != uiHostID)
        {
            continue;
        }

        MsgGridItemInfo* pstGridItemInfo = stMsgObjBase.add_treasure_info();

        if (!pstGridItemInfo) {continue;}

        GetBriefTreasure(stTreasureUnit._chHostPos - 1, stTreasureUnit,
            (*pstGridItemInfo));

        ++iCount;
    }
}

int CTreasureMgr::GetTreasureFighting(CPlayerDetailInfo& stPlayerDetail,
        char chHostType, unsigned int uiHostID)
{
    CTreasureData& stTreasureData = stPlayerDetail._stTreasureData;

    int iCount = 0;
    int iTreasureFighting = 0;

    for (int i = 0; i < stTreasureData._stTreasureList.Size() &&
            iCount < MAX_TREASURE_OBJ_COUNT; ++i)
    {
        CTreasureUnit& stTreasureUnit = stTreasureData._stTreasureList[i];
        if (!IsValidTreasureID(stTreasureUnit._shResID))
        {
            continue;
        }

        if (stTreasureUnit._chHostType != chHostType ||
            stTreasureUnit._uiHostID != uiHostID)
        {
            continue;
        }

        iTreasureFighting +=
            ((stTreasureUnit._shLevel + 1) * TREASURE_LEVEL_ADD_FIGHTING);

        ++iCount;
    }

    return iTreasureFighting;
}

void CTreasureMgr::SendBriefTreasureToFront(CPlayerDetailInfo& stPlayerDetail)
{
    int iIndex = 0;
    MsgAnsUserStorageInfo stAns;
    CTreasureData& stTreasureData = stPlayerDetail._stTreasureData;

    stAns.set_gid(stPlayerDetail._uiGID);
    stAns.set_storage_type(STORAGE_TYPE_TREASURE);
    stAns.set_grid_total_num(MAX_TREASURE_ACT_COUNT);
    stAns.set_grid_unlocked_num(0);

    for (int i = 0; i < stTreasureData._stTreasureList.Size(); ++i)
    {
        CTreasureUnit& stTreasureUnit = stTreasureData._stTreasureList[i];
        if (!IsValidTreasureID(stTreasureUnit._shResID))
        {
            continue;
        }

        if (stTreasureUnit._shResID <= 0)
        {
            continue;
        }

        iIndex = FindTreasureCfg(stTreasureUnit._shResID);
        if (iIndex < 0)
        {
            CT_ERROR(("treasure(%d) config empty!",stTreasureUnit._shResID));
            continue;
        }

        CTreasureCfgData& stCfgData = GetTreasureCfg(iIndex);

        MsgGridItemInfo* pstGridItemInfo = stAns.add_grid_items();

        if (!pstGridItemInfo) {continue;}

        GetBriefTreasure(stCfgData.GetOrder() - 1, stTreasureUnit,
            (*pstGridItemInfo));
    }

    stAns.set_grid_default_num(stAns.grid_items_size());

    CMainCtrl::m_pstMain->NotifyOnlineUser(stPlayerDetail._uiGID,
        ID_MAIN_GET_USER_STORAGE_INFO, stAns, false);
}

void CTreasureMgr::GetDetailTreasure(CTreasureUnit& stTreasureUnit,
        MsgTreasureDetail& stMsgDetail)
{
	stMsgDetail.set_id(stTreasureUnit._shResID);
	stMsgDetail.set_level(stTreasureUnit._shLevel);
    stMsgDetail.set_host_type(stTreasureUnit._chHostType);
    stMsgDetail.set_host_id(stTreasureUnit._uiHostID);
    stMsgDetail.set_host_pos(stTreasureUnit._chHostPos);
}

void CTreasureMgr::GetObjectDetailTreasure(CPlayerDetailInfo& stPlayerDetail,
        char chHostType, unsigned int uiHostID, MsgAnsOtherInfo& stMsgOtherInfo)
{
    if (GAME_OBJ_TYPE_PLAYER != chHostType && 
        GAME_OBJ_TYPE_PARTNER != chHostType)
    {
        return;
    }

    int iNum = 0;
    CTreasureData& stTreasureData = stPlayerDetail._stTreasureData;

    for (int i = 0; i < stTreasureData._stTreasureList.Size() &&
            iNum < MAX_TREASURE_OBJ_COUNT; ++i)
    {
        CTreasureUnit& stTreasureUnit = stTreasureData._stTreasureList[i];
        if (stTreasureUnit._chHostType != chHostType ||
            stTreasureUnit._uiHostID != uiHostID)
        {
            continue;
        }

        MsgTreasureDetail* pstTreasureDetail =
            stMsgOtherInfo.add_treasure_info();

        if (!pstTreasureDetail) {continue;}

        GetDetailTreasure(stTreasureUnit, (*pstTreasureDetail));
        ++iNum;
    }
}

void CTreasureMgr::GetTreasureInfo(CPlayerDetailInfo& stPlayerDetail, MsgPlayerInfo& stMsgInfo)
{

    CTreasureData& stTreasureData = stPlayerDetail._stTreasureData;

    for (int i = 0; i < stTreasureData._stTreasureList.Size(); ++i)
    {
        CTreasureUnit& stTreasureUnit = stTreasureData._stTreasureList[i];

        MsgTreasureDetail* pstTreasureDetail = stMsgInfo.add_treasure_info();

        if (!pstTreasureDetail) {continue;}

        GetDetailTreasure(stTreasureUnit, (*pstTreasureDetail));
    }
}


int CTreasureMgr::GetDetailTreasureInfo(CPlayerDetailInfo& stPlayerDetail,
        short shTreasureID, MsgAnsItemDetailInfos& stMsgDetailInfo)
{
    int iIndex = 0;
    stMsgDetailInfo.set_gid(stPlayerDetail._uiGID);
    stMsgDetailInfo.set_partner_id(0);
    stMsgDetailInfo.set_storage_type(STORAGE_TYPE_TREASURE);
    stMsgDetailInfo.set_item_type(ITEM_TYPE_TREASURE);

    iIndex = FindTreasureIndex(shTreasureID, stPlayerDetail);
    if (iIndex < 0)
    {
        CT_ERROR(("role(%u) treasure(%d) not exist!",stPlayerDetail._uiGID,
            shTreasureID));
        return ERROR_TREASURE_NOT_EXIST;
    }

    CTreasureUnit& stTreasureUnit = GetTreasureUnit(iIndex, stPlayerDetail);

    MsgTreasureDetail* pstTreasureDetail = stMsgDetailInfo.add_treasure_infos();

    if (!pstTreasureDetail) {return RET_SYS_NULL_POINTER;}

    GetDetailTreasure(stTreasureUnit, (*pstTreasureDetail));

    return 0;
}

void CTreasureMgr::SendDetailTreasureToFront(CPlayerDetailInfo& stPlayerDetail,
        short shTreasureID)
{
    int iRet = 0;
    MsgAnsItemDetailInfos stAns;

    iRet = GetDetailTreasureInfo(stPlayerDetail, shTreasureID, stAns);
    if (iRet)
    {
        CT_ERROR(("role(%u) get treasure(%d) detail info error(%d)",
            stPlayerDetail._uiGID,shTreasureID,iRet));
        return;
    }

    CMainCtrl::m_pstMain->NotifyOnlineUser(stPlayerDetail._uiGID,
        ID_MAIN_GET_ITEM_DETAIL_INFO, stAns, false);
}

void CTreasureMgr::SendDetailTreasureToFront(CPlayerDetailInfo& stPlayerDetail,
        const ::google::protobuf::RepeatedField<int64>& stReqIDList)
{
    int iRet = 0;
    MsgAnsItemDetailInfos stAns;
    for (int i = 0; i < stReqIDList.size(); ++i)
    {
        const int iTreasureID = CT_UINT_LOW(stReqIDList.Get(i));

        iRet = GetDetailTreasureInfo(stPlayerDetail, iTreasureID, stAns);
        if (iRet)
        {
            CT_ERROR(("role(%u) get treasure(%d) detail info error(%d)",
                stPlayerDetail._uiGID,iTreasureID,iRet));
            return;
        }
    }

    CMainCtrl::m_pstMain->NotifyOnlineUser(stPlayerDetail._uiGID,
        ID_MAIN_GET_ITEM_DETAIL_INFO, stAns, false);
}

int CTreasureMgr::GMDealTreasure(CPlayerDetailInfo& stPlayerDetail,
        MsgReqGMPlayer& stReq, MsgAnsGMPlayer& stAns)
{
    CTSizeString<MAX_BATTLE_NAME_BUFF> szNameStr;

    switch (stReq.sub_type())
    {
    case ID_GM_PLAYER_SUB_GET_TREASURE://查看角色秘宝
        {
            CTreasureData& stTreasure = stPlayerDetail._stTreasureData;
            szNameStr.Cat("秘宝灵力:%d ",stTreasure._iSpirit);
            szNameStr.Cat("秘宝总数:%d ",stTreasure._stTreasureList.Size());
            for (int i = 0; i < stTreasure._stTreasureList.Size(); ++i)
            {
                CTreasureUnit& stUnitData = stTreasure._stTreasureList[i];

                szNameStr.Cat("\n秘宝ID:%d ",stUnitData._shResID);
                szNameStr.Cat("秘宝等级:%d ",stUnitData._shLevel);
                szNameStr.Cat("宿主类型:%d ",stUnitData._chHostType);
                szNameStr.Cat("宿主ID:%u ",stUnitData._uiHostID);
                szNameStr.Cat("宿主配位:%d ",stUnitData._chHostPos);
            }

            stAns.set_name(szNameStr.Get());
        }
        break;
    case ID_GM_PLAYER_SUB_SET_TREASURE://设置角色秘宝
        if (stReq.datas_size() >= 1 && stReq.datas(0) > 0)
        {
            short shResID = (short)stReq.datas(0);
            if (!IsRoleGetTreasure(shResID, stPlayerDetail))
            {
                RoleGetTreasure(shResID, stPlayerDetail);
            }
        }
        break;
    case ID_GM_PLAYER_SUB_SET_SPIRIT:
        if (stReq.datas_size() >= 1 && stReq.datas(0) != 0)
        {
            stPlayerDetail._stTreasureData._iSpirit += stReq.datas(0);
            if (stPlayerDetail._stTreasureData._iSpirit < 0)
            {
                stPlayerDetail._stTreasureData._iSpirit = 0;
            }

            CMainCtrl::m_pstMain->m_stNotifyMgr.Notify(stPlayerDetail._uiGID,
                    NOTIFY_ROLE_INFO);
        }
        break;
    default:
        return ERROR_MAIN_SUB_CMD;
    }

    return 0;
}

int CTreasureMgr::GetTreasureList(char chHostType, unsigned int uiHostID,
        CPlayerDetailInfo& stPlayerDetail,
        CTreasureData::T_TREASURE_LIST& astTreasureList)
{
    astTreasureList.Clear();

    if (GAME_OBJ_TYPE_PLAYER != chHostType && 
        GAME_OBJ_TYPE_PARTNER != chHostType)
    {
        return 0;
    }

    int iIndex = 0;
    CTreasureObj stTreasureObj;
    CTreasureData& stTreasureData = stPlayerDetail._stTreasureData;

    for (int i = 0; i < stTreasureData._stTreasureList.Size() &&
            astTreasureList.Size() < MAX_TREASURE_OBJ_COUNT; ++i)
    {
        CTreasureUnit& stTreasureUnit = stTreasureData._stTreasureList[i];
        if (stTreasureUnit._chHostType != chHostType ||
            stTreasureUnit._uiHostID != uiHostID)
        {
            continue;
        }

        iIndex = FindTreasureCfg(stTreasureUnit._shResID);
        if (iIndex < 0)
        {
            CT_WARNING(("role(%u) treasure(%d) can not find config!",
                        stPlayerDetail._uiGID, stTreasureUnit._shResID));
            continue;
        }

        CTreasureCfgData& stTreasureCfgData = GetTreasureCfg(iIndex);

        stTreasureObj._shStatusID =
            stTreasureCfgData.GetStatusID(stTreasureUnit._shLevel);
        if (stTreasureObj._shStatusID <= 0)
        {
            continue;
        }

        stTreasureObj._shResID = stTreasureUnit._shResID;

        astTreasureList.AddOneItem(stTreasureObj);
    }

    return 0;
}

int CTreasureMgr::GetTreasureStatusList(char chHostType, unsigned int uiHostID,
        CPlayerDetailInfo& stPlayerDetail, CStatusList& stStatusList)
{
    if (GAME_OBJ_TYPE_PLAYER != chHostType && 
        GAME_OBJ_TYPE_PARTNER != chHostType)
    {
        return 0;
    }

    int iIndex = 0;
    CStatusObj stStatusObj;

    stStatusObj._iAddNum = 1;       //叠加层数 这里必须规定正数
    stStatusObj._iSrcType = STATUS_SOURCE_OBJ_TREASURE;

    CTreasureData& stTreasureData = stPlayerDetail._stTreasureData;

    for (int i = 0; i < stTreasureData._stTreasureList.Size(); ++i)
    {
        CTreasureUnit& stTreasureUnit = stTreasureData._stTreasureList[i];
        if (stTreasureUnit._chHostType != chHostType ||
            stTreasureUnit._uiHostID != uiHostID)
        {
            continue;
        }

        iIndex = FindTreasureCfg(stTreasureUnit._shResID);
        if (iIndex < 0)
        {
            CT_ERROR(("role(%u) treasure(%d) can not find config!",
                stPlayerDetail._uiGID, stTreasureUnit._shResID));
            continue;
        }

        CTreasureCfgData& stTreasureCfgData = GetTreasureCfg(iIndex);

        stStatusObj._iResID =
            stTreasureCfgData.GetStatusID(stTreasureUnit._shLevel);
        if (stStatusObj._iResID <= 0)
        {
            CT_ERROR(("role(%u) treasure(%d) status id empty(%d)!",
                stPlayerDetail._uiGID, stTreasureUnit._shResID,
                stStatusObj._iResID));
            continue;
        }

        stStatusObj._uiSrcResID = (unsigned int)stTreasureUnit._shResID;

        stStatusList._astStatus.AddOneItem(stStatusObj);
    }

    return 0;
}

int CTreasureMgr::TakeOffPartnerTreasure(short shResID,
        CPlayerBaseInfo& stPlayerBase, CPlayerDetailInfo& stPlayerDetail,
        CPlayerOnlineData& stPlayerOnline)
{
    int iRet = 0;
    int iCount = 0;
    CTreasureData& stTreasureData = stPlayerDetail._stTreasureData;

    MsgReqTreasure stTakeOffReq;
    stTakeOffReq.set_gid((int)stPlayerDetail._uiGID);
    stTakeOffReq.set_sub_type(CMD_TREASURE_SUB_TAKE_OFF);

    for (int i = 0; i < stTreasureData._stTreasureList.Size() &&
            iCount < MAX_TREASURE_OBJ_COUNT; ++i)
    {
        CTreasureUnit& stTreasureUnit = stTreasureData._stTreasureList[i];
        if (stTreasureUnit._chHostType != GAME_OBJ_TYPE_PARTNER ||
            stTreasureUnit._uiHostID != (unsigned int)shResID)
        {
            continue;
        }

        stTakeOffReq.set_treasure_id(stTreasureUnit._shResID);
        
        iRet = TreasureTakeOff(stPlayerBase, stPlayerDetail, stPlayerOnline,
            stTakeOffReq);
        CT_RETURN(iRet);
        ++iCount;
    }

    return 0;
}

bool CTreasureMgr::IsRoleGetTreasure(short shResID,
        CPlayerDetailInfo& stPlayerDetail)
{
    int iIndex = 0;
    iIndex = FindTreasureIndex(shResID, stPlayerDetail);
    if (iIndex < 0)
    {
        return false;
    }

    CTreasureUnit& stTreasureUnit = GetTreasureUnit(iIndex, stPlayerDetail);

    if (stTreasureUnit._shResID != shResID)
    {
        return false;
    }

    return true;
}

int CTreasureMgr::RoleGetTreasure(short shResID,
        CPlayerDetailInfo& stPlayerDetail)
{
    int iRet = 0;
    CT_TRACE(("role(%u) get treasure(%d) begin",stPlayerDetail._uiGID,shResID));

    if (IsRoleGetTreasure(shResID, stPlayerDetail))
    {
        return ERROR_TREASURE_GET_ALREADY;
    }

    CTreasureUnit stTreasureUnit;

    stTreasureUnit._chHostType = GAME_OBJ_TYPE_NULL;
    stTreasureUnit._chHostPos = TREASURE_HOST_POS_NULL;
    stTreasureUnit._shResID = shResID;
    stTreasureUnit._shLevel = 0;
    stTreasureUnit._uiHostID = 0;

    iRet = stPlayerDetail._stTreasureData._stTreasureList.AddOneItem(
        stTreasureUnit);
    if (iRet < 0)
    {
        CT_ERROR(("role(%u) add treasure(%d) error(%d)",stPlayerDetail._uiGID,
                  shResID,iRet));
        return ERROR_TREASURE_OPERATION_INFO;
    }

    //下发简略信息
    SendBriefTreasureToFront(stPlayerDetail);

    //下发详细单体信息
    SendDetailTreasureToFront(stPlayerDetail, shResID);

    CT_TRACE(("role(%u) get treasure(%d) end",stPlayerDetail._uiGID,shResID));

    return 0;
}

int CTreasureMgr::CheckValidOrder(T_TREASURE_ACT_DATA& aiTreasureOrder)
{
    int iTmpMask = 0;
    int iOrderMask = 0;
    for (int i = 0; i < aiTreasureOrder.Size(); ++i)
    {
        if (aiTreasureOrder[i] <= 0 ||
            aiTreasureOrder[i] > MAX_TREASURE_ACT_COUNT)
        {
            return ERROR_TREASURE_ORDER_OVER;
        }

        iTmpMask = (0x1 << aiTreasureOrder[i]);
        if (iOrderMask & iTmpMask)
        {
            return ERROR_TREASURE_ORDER_REPEAT;
        }
        iOrderMask |= iTmpMask;
    }

    return 0;
}

